package com.itany.corejava.code10_异常;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author 石小俊
 * @date 2023年05月09日 11:24
 */
public class Test02_异常处理 {

    public static void main(String[] args) throws Exception {
        test01();
        // 当调用test02方法时,由于该方法存在未处理的异常
        // 因此,此时需要对该异常进行处理
        // 如果,此处仍然通过throws抛出去,最终会交到JVM中进行处理
        // test02("2022-02-02");

//        int i = test03(2, 0);
//        System.out.println(i);
    }

    /**
     * 使用try-catch-finally语句处理异常
     */
    public static void test01() {
        try {
            System.out.println("可能出现异常的代码");
            int i = 1 / 0;
            // int i = 2 / 1;
            System.out.println("没有出现异常执行的代码");
        } catch (ArithmeticException e) {
            // 在catch中需要捕获的异常类型
            System.out.println("当遇到ArithmeticException异常时执行的代码");
            // 异常对象中包含了异常的详细信息
            // 打印堆栈中异常详细信息,通过单独的线程进行打印
            // System.err.println()
            // System.out.println("Hello World");
            // System.err.println("Hello Exception");
            // e.printStackTrace();
            // 获取异常信息
            System.out.println(e);
            // 获取异常信息的字符串
            System.out.println(e.getMessage());
            // 此处return虽然表示退出方法,但是try-catch-finally并没有退出
            // 此时return之后finally依然会执行,但是try-catch-finally后面的代码不会执行
            // return;
            // System.exit(0)表示终止当前正在运行的JVM。
            // 即:系统完全退出,此时finally不会执行
            System.exit(0);
        } finally {
            System.out.println("无论是否存在异常都必须执行的代码");
        }

        System.out.println("异常后面的代码,此处代码与异常无关");
    }

    /**
     * 使用throws处理异常
     * 当方法中存在多个异常时,多个异常之间以逗号分隔即可
     */
    public static void test02(String s) throws ParseException, ClassNotFoundException {
        // 方式一:通过catch捕获到指定异常之后然后抛出去
        try {
            Date date = new SimpleDateFormat("yyyy-MM-dd").parse(s);
        } catch (ParseException e) {
            // 此处表示捕获到对应异常,可以进行处理
            System.out.println("解析失败:" + s + "格式有误");
            // 此处也可以使用throw关键字将异常抛出去,不进行处理
            // throw后面跟的是异常对象,通过new XXX()创建对应的异常对象
            // 也可以直接抛出当前捕获到的异常对象
            // 当此处抛出异常对象后,方法的声明中必须添加throws 异常类型来表示当前方法抛出的异常
            throw e;
        }

        // 方式二:直接使用throws声明会抛出的异常,不进行捕获
        Class.forName("java.lang.Test");
    }

    /**
     * 计算两数相除的结果
     */
    public static int test03(int num1, int num2) throws Exception {
        // 此时如果num2的值为0,会存在异常
        // 开发者需要对这种情况进行处理
        if (num2 == 0) {
            // 由于只有num2的值为0时有异常
            // 因此,此处不需要通过try-catch来捕获
            // 而是判断当num2的值为0时处理异常、
            // 异常构造方法的参数可以指定,属于异常消息
            // ArithmeticException e = new ArithmeticException("第二个参数的值不能为0,否则除数为0");
            // throw e;
            // 简写方式
            // 对于运行时异常,方法不需要通过throws声明,此时的方法处没有throws
            // throw new ArithmeticException("第二个参数的值不能为0,否则除数为0");
            // 对于检查异常,方法必须声明
            // throw相当于return,表示代码结束
            throw new Exception("这是检查异常");
            // System.out.println("此处代码不会执行");
        }
        return num1 / num2;
    }


}
